﻿using System;
using System.Collections.Generic;
using System.Text;
using FieldLib;
using FieldDevice.ModBus;
namespace FieldDevice.Devices
{
    class DevicePM800 : Device
    {
        public DevicePM800(byte address, string name)
            :base(DeviceCategory.PowerMeter, address, name)
        {
            Initialize();
        }


        public DevicePM800(byte address)
            : base(DeviceCategory.PowerMeter, address)
        {
            Initialize();
        }

        public override void DebugReads()
        {
            if (DeviceManager.GlobalDeviceManager.ModBusIO.IsEmulation)
                this.UpdateReads();
            else
                base.DebugReads();
        }

        void UpdateReads()
        {
            ReadRegValue(Emulation.PM800Emulator.ADDR1100_Ia, 30);
            //ReadRegValue(Emulation.PM800Emulator.ADDR1143_P, 40);
            //ReadRegValue(Emulation.PM800Emulator, 10);
        }


        void Initialize()
        {
            base.RequestRegister(Emulation.PM800Emulator.ADDR1100_Ia, 30);
            //base.RequestRegister(Emulation.PM800Emulator.ADDR1143_P, 40);
            //base.RequestRegister(Emulation.PM800Emulator.ADDR_EP_Hi, 10);

        }
         
         int P = 0;
         int Q = 0;
         int S = 0;
         int Kwh = 0;
         int Kvarh = 0;
        byte[] RegistersValue = new byte[522];

        /**************************************
         * DataAddr设置要读取的寄存器的起始地址，
         * DataNumber设置要读取的寄存器个数
        ***************************************/
        public void ReadRegValue(ushort DataAddr, ushort DataNumber)
        {
            ModBusPacket packet=new ModBusPacket();
            packet.SlaveAddress = (byte)this.ModbusAddress;
            packet.Function = ModBus.ModBusFunction.READHOLDINGREGISTER;
            packet.DataAddressHi = (byte)(DataAddr >> 8);
            packet.DataAddressLow = (byte)(DataAddr & 0x00ff);
            packet.DataNumberHi = (byte)(DataNumber >> 8);
            packet.DataNumberLow = (byte)(DataNumber & 0x00ff);

            DeviceManager.GlobalDeviceManager.ModBusIO.Send(this, packet);
            RegistersValue = DeviceManager.GlobalDeviceManager.ModBusIO.Receive(this);
            TranslateRegister(DataAddr, RegistersValue);
        }

        /*
         * 通过寄存器的起始地址DataAddr和
         * 返回的值来读取电压、电流、功率等值 
         */
        public void  TranslateRegister(ushort DataAddr,byte[] value)
        {
            if (value.Length <=3)                       //判断通信得到的数据是否小于三个
            {
             //   throw new Exception("Datas Wrong");
                return;
            }
            else
            {
                if (value.Length != value[2] + 5)       //判断返回的数据是否完整
                    //    throw new Exception("Data Wrong");
                    return;
                else
                {
                    byte CRCHi;
                    byte CRCLow;
                    short tmpValue;
                    CRC.CRC16(value, value.Length - 2, out CRCHi, out CRCLow);
                    if (CRCHi != value[value.Length - 2] && CRCLow != value[value.Length - 1])
                    { throw new Exception("Data Wrong"); }
                   
                    /********************************************************
                     * 对返回的值进行翻译，通过value[2]可知道读取的寄存器的个数是value[2]/2，
                     * 由DataAddr可知其实地址，循环保存数值到相应的列表中
                     *******************************************************/
                    for (int i = 0; i < value[2]; i+=2)             
                    {   
                        tmpValue = value[3 + i];
                        tmpValue <<= 8;
                        tmpValue += value[4 + i];
                        switch (DataAddr + i/2)
                        {
                            case Emulation.PM800Emulator.ADDR1100_Ia:
                                RecordRead("IA", tmpValue);
                                break;
                            case Emulation.PM800Emulator.ADDR1101_Ib:
                                RecordRead("IB", tmpValue);
                                break;
                            case Emulation.PM800Emulator.ADDR1102_Ic:
                                RecordRead("IC", tmpValue);
                                break;
                            case Emulation.PM800Emulator.ADDR1120_Vab:
                                RecordRead("Vab", tmpValue);
                                break;
                            case Emulation.PM800Emulator.ADDR1121_Vbc:
                                RecordRead("Vbc", tmpValue);
                                break;
                            case Emulation.PM800Emulator.ADDR1122_Vca:
                                RecordRead("Vca", tmpValue);
                                break;
                            case Emulation.PM800Emulator.ADDR1124_Va:
                                RecordRead("VA", tmpValue);
                                break;
                            case Emulation.PM800Emulator.ADDR1125_Vb:
                                RecordRead("VB", tmpValue);
                                break;
                            case Emulation.PM800Emulator.ADDR1126_Vc:
                                RecordRead("VC", tmpValue);
                                break;

                            case Emulation.PM800Emulator.ADDR1143_P_Hi:
                                RecordRead("P", tmpValue);
                                break;

                            case Emulation.PM800Emulator.ADDR1147_Q_Hi:
                                RecordRead("Q", tmpValue);
                                break;

                            case Emulation.PM800Emulator.ADDR1151_S_Hi:
                                RecordRead("S", tmpValue);
                                break;

                            case Emulation.PM800Emulator.ADDR1180_F:
                                RecordRead("F", tmpValue/100);
                                break;

                            default:
                                break;
                        }

                    }
                }
            }
        }
        protected override float Translate(byte[] value, int begin, ushort registeraddress)
        {
            ushort tmpValue = value[begin];
            tmpValue <<= 8;
            tmpValue += value[begin + 1];
            TranslateRegister(registeraddress, value);
            switch (registeraddress)
            {
                case Emulation.PM800Emulator.ADDR1100_Ia:
                    RecordRead("IA", tmpValue);
                    break;
                case Emulation.PM800Emulator.ADDR1101_Ib:
                    RecordRead("IB", tmpValue);
                    break;
                case Emulation.PM800Emulator.ADDR1102_Ic:
                    RecordRead("IC", tmpValue);
                    break;
                case Emulation.PM800Emulator.ADDR1120_Vab:
                    RecordRead("Vab", tmpValue);
                    break;
                case Emulation.PM800Emulator.ADDR1121_Vbc:
                    RecordRead("Vbc", tmpValue);
                    break;
                case Emulation.PM800Emulator.ADDR1122_Vca:
                    RecordRead("Vca", tmpValue);
                    break;
                case Emulation.PM800Emulator.ADDR1124_Va:
                    RecordRead("VA", tmpValue);
                    break;
                case Emulation.PM800Emulator.ADDR1125_Vb:
                    RecordRead("VB", tmpValue);
                    break;
                case Emulation.PM800Emulator.ADDR1126_Vc:
                    RecordRead("VC", tmpValue);
                    break;
                    
                case Emulation.PM800Emulator.ADDR1143_P_Hi:
                    P = tmpValue<<8;
                    break;
                case Emulation.PM800Emulator.ADDR1144_P_Low:
                    P += tmpValue;
                    RecordRead("P", tmpValue);
                    break;

                case Emulation.PM800Emulator.ADDR1147_Q_Hi:
                    Q = tmpValue<<8;
                    break;
                case Emulation.PM800Emulator.ADDR1148_Q_Low:
                    Q += tmpValue;
                    RecordRead("Q", tmpValue);
                    break;
                case Emulation.PM800Emulator.ADDR1151_S_Hi:
                    S = tmpValue << 8;                
                    break;
                case Emulation.PM800Emulator.ADDR1152_S_Low:
                    S += tmpValue;
                    RecordRead("S", tmpValue);
                    break;
                case Emulation.PM800Emulator.ADDR1180_F:
                    RecordRead("F", tmpValue / 100);
                    break;
                default:
                    break;
            }
            return 0.0f;
        }
     
    }
}
